package com.lijinjiang.view;

import com.lijinjiang.model.GlobalContext;
import com.lijinjiang.model.tree.Database;
import com.lijinjiang.model.tree.ServerConnection;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;

/**
 * @ClassName TreeMenu
 * @Description 树节点右键菜单
 * @Author Li
 * @Date 2022/8/15 16:06
 * @ModifyDate 2022/8/15 16:06
 * @Version 1.0
 */
public class TreeMenu extends JPopupMenu {
    private GlobalContext ctx; // 上下文环境
    private MainFrame mainFrame; // 主窗口
    private LeftPane leftPane; // 左面板
    private JTree tree;

    // 服务器连接节点菜单
    private JMenuItem openSCItem = new JMenuItem("打开连接", null);
    private JMenuItem closeSCItem = new JMenuItem("关闭连接", null);
    private JMenuItem editSCItem = new JMenuItem("编辑连接", null);
    private JMenuItem removeSCItem = new JMenuItem("删除连接", null);
    private JMenuItem newDatabaseItem = new JMenuItem("新建数据库", null);

    // 数据库连接节点菜单
    private JMenuItem openDatabaseItem = new JMenuItem("打开数据库", null);
    private JMenuItem closeDatabaseItem = new JMenuItem("关闭数据库", null);
    private JMenuItem removeDatabaseItem = new JMenuItem("删除数据库", null);
    private JMenuItem createQueryItem = new JMenuItem("新建查询", null);

    /* 构造方法 */
    public TreeMenu(GlobalContext ctx, MainFrame mainFrame, LeftPane leftPane) {
        this.ctx = ctx;
        this.mainFrame = mainFrame;
        this.leftPane = leftPane;
        tree = leftPane.getTree();
        initTreeMenuItemListeners(); // 初始化树节点右键功能
    }

    // 初始化右键功能
    private void initTreeMenuItemListeners() {
        /* 右键服务连接所有功能的实现 */
        this.openSCItem.addActionListener(e -> openSCAction(e)); // 打开连接
        this.closeSCItem.addActionListener(e -> closeSCAction()); // 关闭连接
        this.editSCItem.addActionListener(e -> editSCAction()); // 编辑连接
        this.removeSCItem.addActionListener(e -> removeSCAction()); // 删除连接
        this.newDatabaseItem.addActionListener(e -> newDatabaseAction()); // 新建数据库*/

        /* 右键数据库连接所有功能的实现 */
        this.openDatabaseItem.addActionListener(e -> openDatabaseAction()); // 打开数据库
        this.closeDatabaseItem.addActionListener(e -> closeDatabaseAction()); // 关闭数据库
        this.removeDatabaseItem.addActionListener(e -> removeDatabaseAction()); // 关闭数据库
        this.createQueryItem.addActionListener(e -> createQueryAction()); // 新建查询
    }

    // 显示树的右键菜单
    public void showTreeMenu(MouseEvent e) {
        DefaultMutableTreeNode selectNode = leftPane.getSelectNode();
        if (selectNode == null) return;
        if (selectNode.getUserObject() instanceof ServerConnection) { // 右键服务器连接节点
            createSCMenu(); // 显示服务器连接节点的右键菜单
            this.show(this.tree, e.getX(), e.getY());
            ServerConnection sc = (ServerConnection) selectNode.getUserObject();
            if (sc.getConnection() == null) {
                // 未连接时：打开连接可用，关闭连接不可用，新建数据库不可用，编辑连接可用
                this.openSCItem.setEnabled(true);
                this.closeSCItem.setEnabled(false);
                this.newDatabaseItem.setEnabled(false);
                this.editSCItem.setEnabled(true);
            } else {
                // 已连接时：打开连接不可用，关闭连接可用，新建数据库可用，编辑连接不可用
                this.openSCItem.setEnabled(false);
                this.closeSCItem.setEnabled(true);
                this.newDatabaseItem.setEnabled(true);
                this.editSCItem.setEnabled(false);
            }
        } else if (selectNode.getUserObject() instanceof Database) { // 右键数据库节点
            // System.out.println("右键数据库节点");
            createDatabaseMenu(); // 显示数据库连接节点的右键菜单
            this.show(this.tree, e.getX(), e.getY());
            Database db = (Database) selectNode.getUserObject();
            if (db.getConnection() == null) {
                // 未连接时：打开数据库连接可用,关闭数据库连接不可用
                this.openDatabaseItem.setEnabled(true);
                this.closeDatabaseItem.setEnabled(false);
                this.removeDatabaseItem.setEnabled(true);
            } else {
                // 已连接时：打开数据库连接不可用,关闭数据库连接可用
                this.openDatabaseItem.setEnabled(false);
                this.closeDatabaseItem.setEnabled(true);
                this.removeDatabaseItem.setEnabled(false);
            }
        }
    }

    // 显示服务器连接节点的右键菜单
    private void createSCMenu() {
        this.removeAll();
        this.add(openSCItem);
        this.add(closeSCItem);
        this.add(new JPopupMenu.Separator());
        this.add(editSCItem);
        this.add(removeSCItem);
        this.add(new JPopupMenu.Separator());
        this.add(newDatabaseItem);
    }

    // 显示数据库连接节点的右键菜单
    private void createDatabaseMenu() {
        this.removeAll();
        this.add(openDatabaseItem);
        this.add(closeDatabaseItem);
        this.add(new JPopupMenu.Separator());
        this.add(removeDatabaseItem);
        this.add(new JPopupMenu.Separator());
        this.add(createQueryItem);
    }

    /**
     * 右键服务器连接节点
     */
    // 打开服务器连接功能实现
    protected void openSCAction(ActionEvent e) {
        DefaultMutableTreeNode selectNode = leftPane.getSelectNode();
        leftPane.openServerNode(selectNode);
    }

    // 关闭服务器连接
    private void closeSCAction() {
        DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
        ServerConnection sc = (ServerConnection) selectNode.getUserObject();
        sc.setConnection(null); // 将ServerConnection的连接对象设为null
        removeNodeChildren(selectNode); // 删除该节点下的所有节点
        // this.tree.setSelectionPath(null); // 设置树不选中
        //leftPane.setDataListEmpty(); // 设置右边的数据为空
    }

    // 删除该节点下的所有节点
    private void removeNodeChildren(DefaultMutableTreeNode node) {
        // 获取节点数量
        int childCount = this.leftPane.getTreeModel().getChildCount(node);
        for (int i = 0; i < childCount; i++) {
            // 从最后一个节点开始删除节点
            this.leftPane.getTreeModel().removeNodeFromParent((DefaultMutableTreeNode) node.getLastChild());
        }
    }

    // 编辑服务器连接
    private void editSCAction() {
        DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
        ServerConnection sc = (ServerConnection) selectNode.getUserObject();
        new SCDialog(ctx, this.mainFrame, sc);
    }

    // 删除一个连接
    private void removeSCAction() {
        int option = JOptionPane.showConfirmDialog(this,
                "你确认要删除这个连接吗？", "确认删除", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
        // System.out.println(confirm); 0-确定；2-取消；-1-关闭
        if (option == JOptionPane.OK_OPTION) { // 确认删除
            DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
            ServerConnection sc = (ServerConnection) selectNode.getUserObject();
            // 从上下文中删除,包括删除配置文件
            this.ctx.removeSC(sc);
            // 从树节点中删除
            this.leftPane.getTreeModel().removeNodeFromParent(selectNode);
        }
    }

    // 右键新建数据库
    private void newDatabaseAction() {
        DefaultMutableTreeNode selectNode = leftPane.getSelectNode();
        ServerConnection sc = (ServerConnection) selectNode.getUserObject();
        new DBDialog(sc, this.mainFrame);
    }

    /**
     * 右键数据库节点
     */
    // 打开数据库操作
    private void openDatabaseAction() {
        DefaultMutableTreeNode selectNode = leftPane.getSelectNode();
        leftPane.openDatabaseNode(selectNode);
        leftPane.setObjectPaneData(selectNode);
    }

    // 关闭数据库连接操作
    private void closeDatabaseAction() {
        DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
        Database db = (Database) selectNode.getUserObject();
        db.setConnection(null); // 将 ServerConnection 的连接对象设为null
        removeNodeChildren(selectNode); // 删除该节点下的所有节点
        leftPane.setObjectPaneData(selectNode);
    }

    // 删除数据库
    private void removeDatabaseAction() {
        DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
        Database db = (Database) selectNode.getUserObject();
        String dbName = db.getDbName();
        if ("information_schema".equals(dbName) || "mysql".equals(dbName) || "performance_schema".equals(dbName) || "sys".equals(dbName)) {
            JOptionPane.showMessageDialog(this.mainFrame, dbName + "为系统数据库，不能删除", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }
        int option = JOptionPane.showConfirmDialog(this,
                "确认要删除数据库" + dbName, "确认删除", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
        // System.out.println(confirm); 0-确定；2-取消；-1-关闭
        if (option == JOptionPane.OK_OPTION) { // 确认删除
            // 从上下文中删除,包括删除配置文件
            db.getSc().dropDatabase(db);
            // 从树节点中删除
            this.leftPane.getTreeModel().removeNodeFromParent(selectNode);
            JOptionPane.showMessageDialog(this.mainFrame, "删除数据库" + dbName + "成功", "删除成功", JOptionPane.PLAIN_MESSAGE);
        }
    }

    // 新建查询
    private void createQueryAction() {
        DefaultMutableTreeNode selectNode = this.leftPane.getSelectNode();
        Database db = (Database) selectNode.getUserObject();
        if (db != null){
            mainFrame.getRightPane().createQueryPanel(db);
        } else {
            JOptionPane.showMessageDialog(this.mainFrame, "数据库不存在", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
    }
}
